package recipe.renderer;

import java.util.LinkedList;

public class Task {
	public LinkedList<Task> dependencies; // a list of tasks this task is depended on
	public String id; // task unique ID
	public String speech; // speech at beginning of task
	public String query; // speech asking user if task is done
	public long duration; // in seconds
	public long time_finished; 
	public long time_started;
	public long time_last_queried; // time last queried
	public long time_initialized; // time task was initialized

	public Task(String id) {
		this.id = id;
		dependencies = new LinkedList<Task>();
		speech = "";
		query = "";
		duration = 0;
		// here 0 means not initialized
		time_finished = 0;
		time_started = 0;
		time_last_queried = 0;
		time_initialized = System.currentTimeMillis();
	}
	
	public Task(Task other) {
		this.id = other.id;
		//dependencies = other.dependencies;
		speech = other.speech;
		query = other.query;
		duration = other.duration;
		time_finished = other.time_finished;
		time_started = other.time_started;
		time_last_queried = other.time_last_queried;
		time_initialized = other.time_initialized;
	}

	public void start(long current_time) {
		time_started = current_time;
	}
	
	public void start() {
		start(System.currentTimeMillis());
	}

	public void stop(long current_time) {
		time_finished = current_time;
	}
	public void stop() {
		stop(System.currentTimeMillis());
	}

	public boolean completed() {
		return time_finished > time_initialized;
	}

	public boolean can_start() {
		if (started())
			return false;
		for (Task t : dependencies) {
			if (t!=null && !t.completed())
				return false;
		}
		return true;
	}

	public boolean started() {
		return time_started > time_initialized;
	}

	public boolean is_active() {
		return started() && !completed();
	}
	
	public void query_now() {
		query_now(System.currentTimeMillis());
	}
	
	public void query_now(long current_time) {
		time_last_queried = current_time;
	}

	public boolean is_overdue() {
		return is_overdue(System.currentTimeMillis());
	}
	public boolean is_overdue(long current_time) {
		return is_active() && ((time_started + duration*1000) < current_time);
	}

	public Long ETA() {
		if (time_finished > time_initialized)
            return time_finished;
        if (time_started > time_initialized)
            return time_started + duration*1000;
        long estimated_start;
        if (dependencies.size() > 0) {
        	long max_eta = -1;
        	for (Task d : dependencies) {
        		long eta = d.ETA();
        		if (eta > max_eta)
        			max_eta = eta;
        	}
            estimated_start = max_eta;
        }
        else {
            estimated_start = System.currentTimeMillis();
        }
        return estimated_start + duration*1000;
	}

}
